package com.gmlive.common.sample.update

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import com.gmlive.common.sample.update.entity.AppUpdateEntity
import com.gmlive.common.sample.update.entity.UpdateData
import com.gmlive.common.appupdate.XUpdate
import com.gmlive.common.appupdate.download.DefaultUpdateService
import com.gmlive.common.appupdate.entity.UpdateEntity
import com.gmlive.common.appupdate.entity.UpdateError
import com.gmlive.common.appupdate.listener.IUpdateParseCallback
import com.gmlive.common.appupdate.listener.OnUpdateFailureListener
import com.gmlive.common.appupdate.proxy.IUpdateHttpService
import com.gmlive.common.appupdate.proxy.IUpdateParser
import com.gmlive.common.appupdate.utils.UpdateUtils
import com.gmlive.common.okhttplog.IkOkHttpLogInterceptor
import com.gmlive.common.sample.update.entity.UpdateResult
import com.gmlive.common.sample.update.entity.hasNewVersion
import com.google.gson.Gson
import com.meelive.ingkee.logger.IKLog
import io.objectbox.android.AndroidScheduler
import okhttp3.*
import java.io.IOException

object AppUpdateUtils {

    /**
     * 初始化升级SDK
     */
    fun initUpdateSdk(application: Application) {
        XUpdate.get()
                .isWifiOnly(false)
                .isGet(true)
                .isAutoMode(true)
                .supportSilentInstall(true)
                // 自定义下载器，apk下载已封装，需自定义获取更新信息
                .setIUpdateHttpService(DefaultUpdateService(UpdateDetector()))
                // 自定义更新信息解析器
                .setIUpdateParser(UpdateParser())
                // 自定义更新错误监听
                .setOnUpdateFailureListener(UpdateErrorListener(application))
                .init(application)
    }

    /**
     * 检测升级
     */
    fun checkNewVersion(context: Context, from: String, url: String) {
        XUpdate.newBuild(context)
                .param("scene", from)
                // 新版本提示
                .updatePrompter(AppUpdatePrompter())
                // 获取更新的api地址
                .updateUrl(url)
                .update()
    }

    /**
     * 格式化apk大小
     */
    fun formatApkSize(byteNum: Long): String {
        return when {
            byteNum <= 0 -> {
                ""
            }
            byteNum < 1024 -> {
                String.format("%.1fB", byteNum.toDouble())
            }
            byteNum < 1048576 -> {
                String.format("%.1fKB", byteNum.toDouble() / 1024)
            }
            byteNum < 1073741824 -> {
                String.format("%.1fMB", byteNum.toDouble() / 1048576)
            }
            else -> {
                String.format("%.1fGB", byteNum.toDouble() / 1073741824)
            }
        }
    }

    class UpdateDetector : DefaultUpdateService.IUpdateDetector {
        @SuppressLint("CheckResult")
        override fun detectNewVersion(isGet: Boolean, url: String, params: MutableMap<String, Any>,
                                      callBack: IUpdateHttpService.Callback) {
            val httpLogger = IkOkHttpLogInterceptor() {
                Log.i("HttpLog", it)
            }
            httpLogger.level = IkOkHttpLogInterceptor.Level.BODY

            val client = OkHttpClient.Builder()
                    .addInterceptor(httpLogger)
                    .build()
            val request = Request.Builder()
                    .url(url)
                    .build()
            val call = client.newCall(request)

            call.enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    Handler(Looper.getMainLooper())
                            .post {
                                callBack.onError(e)
                            }
                }

                override fun onResponse(call: Call, response: Response) {
                    Handler(Looper.getMainLooper())
                            .post {
                                callBack.onSuccess(response.body?.string())
                            }
                }
            })
        }
    }

    /**
     * 更新信息解析器，根据具体服务定制解析
     */
    class UpdateParser : IUpdateParser {
        /**
         * json 参照接口的data字段
         */
        override fun parseJson(json: String?): UpdateEntity {
            val data = Gson().fromJson(json, UpdateResult::class.java)
            val entity = AppUpdateEntity(data.data!!.title, data.data!!.cancelText, data.data!!.okText,
                    data.data!!.noVersionPrompt, data.data!!.updateId)
            entity.isHasUpdate = data.data!!.hasNewVersion()
            entity.isForce = data.data!!.isForce == 1
            entity.versionName = data.data!!.version
            entity.downloadUrl = data.data!!.apkUrl
            entity.md5 = data.data!!.md5
            entity.size = data.data!!.apkTotalSize.toLong()
            entity.updateContent = data.data!!.content

            return entity
        }

        override fun parseJson(json: String?, callback: IUpdateParseCallback?) {
            // isAsyncParser 返回true 才会走到这里
        }

        override fun isAsyncParser(): Boolean {
            // false 则调用同步解析方法
            return false
        }
    }

    /**
     * 获取更新信息错误提示
     * @see com.gmlive.common.appupdate.entity.UpdateError.ERROR
     */
    class UpdateErrorListener(private val context: Context) : OnUpdateFailureListener {
        override fun onFailure(error: UpdateError?) {
            error?.let {
                Log.e("HttpLog", "获取更新信息失败：${error.detailMsg}")
                Toast.makeText(context, error.message, Toast.LENGTH_SHORT).show()
            }
        }
    }
}